(require 'package)
(setq package-archives '(("gnu"    . "https://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
                         ("nongnu" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/nongnu/")
                         ("melpa"  . "https://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")))
(package-initialize)
(setq package-check-signature nil)

;; 安装 use-package 如果尚未安装
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

;; 自动安装缺失包
(eval-when-compile
  (require 'use-package))
(setq use-package-always-ensure t)

(use-package restart-emacs
  :ensure t)

;; 加载配置
(add-to-list 'load-path "~/.emacs.d/lisp/")
(require 'memo-mode)

(use-package nerd-icons
  :defer t)

(use-package cnfonts
  :config
  (cnfonts-mode 1)
  (define-key cnfonts-mode-map (kbd "C--") #'cnfonts-decrease-fontsize)
  (define-key cnfonts-mode-map (kbd "C-=") #'cnfonts-increase-fontsize))

(use-package doom-themes
  :config
  (load-theme 'doom-one t))

(use-package doom-modeline
  :config
  (doom-modeline-mode t))

(use-package ivy
  :config
  (ivy-mode 1))

(use-package swiper
  :after ivy)

(use-package counsel
  :after ivy
  :config)

(defun meow-setup ()
  (setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty)
  (meow-motion-define-key
   '("j" . meow-next)
   '("k" . meow-prev)
   '("<escape>" . ignore))
  (meow-leader-define-key
   ;; Use SPC (0-9) for digit arguments.
   '("1" . meow-digit-argument)
   '("2" . meow-digit-argument)
   '("3" . meow-digit-argument)
   '("4" . meow-digit-argument)
   '("5" . meow-digit-argument)
   '("6" . meow-digit-argument)
   '("7" . meow-digit-argument)
   '("8" . meow-digit-argument)
   '("9" . meow-digit-argument)
   '("0" . meow-digit-argument)
   '("/" . meow-keypad-describe-key)
   '("?" . meow-cheatsheet))
  (meow-normal-define-key
   '("0" . meow-expand-0)
   '("9" . meow-expand-9)
   '("8" . meow-expand-8)
   '("7" . meow-expand-7)
   '("6" . meow-expand-6)
   '("5" . meow-expand-5)
   '("4" . meow-expand-4)
   '("3" . meow-expand-3)
   '("2" . meow-expand-2)
   '("1" . meow-expand-1)
   '("-" . negative-argument)
   '(";" . meow-reverse)
   '("," . meow-inner-of-thing)
   '("." . meow-bounds-of-thing)
   '("[" . meow-beginning-of-thing)
   '("]" . meow-end-of-thing)
   '("a" . meow-append)
   '("A" . meow-open-below)
   '("b" . meow-back-word)
   '("B" . meow-back-symbol)
   '("c" . meow-change)
   '("d" . meow-delete)
   '("D" . meow-backward-delete)
   '("e" . meow-next-word)
   '("E" . meow-next-symbol)
   '("f" . meow-find)
   '("g" . meow-cancel-selection)
   '("G" . meow-grab)
   '("h" . meow-left)
   '("H" . (lambda () (interactive) (move-to-window-line 2)))
   '("i" . meow-insert)
   '("I" . meow-open-above)
   '("j" . meow-next)
   '("J" . meow-next-expand)
   '("k" . meow-prev)
   '("K" . meow-prev-expand)
   '("l" . meow-right)
   '("L" . (lambda () (interactive) (move-to-window-line -3)))
   '("m" . meow-join)
   '("M" . (lambda () (interactive) (move-to-window-line nil)))
   '("n" . meow-search)
   '("o" . meow-block)
   '("O" . meow-to-block)
   '("p" . meow-yank)
   '("q" . meow-quit)
   '("Q" . meow-goto-line)
   '("r" . meow-replace)
   '("R" . meow-swap-grab)
   '("s" . meow-kill)
   '("t" . meow-till)
   '("u" . meow-undo)
   '("U" . meow-undo-in-selection)
   '("v" . meow-visit)
   '("w" . meow-mark-word)
   '("W" . meow-mark-symbol)
   '("x" . meow-line)
   '("X" . meow-goto-line)
   '("y" . meow-save)
   '("Y" . meow-sync-grab)
   '("z" . meow-pop-selection)
   '("'" . repeat)
   '("<escape>" . ignore)))

(use-package meow
  :config
  (meow-setup)
  (meow-global-mode t)
  (meow-setup-indicator)
  (with-eval-after-load "meow"
    (custom-set-faces
     '(meow-grab ((t (:inherit secondary-selection))))
     '(meow-normal-indicator ((t ())))
     '(meow-motion-indicator ((t ())))
     '(meow-keypad-indicator ((t ())))
     '(meow-insert-indicator ((t ()))))
    (add-to-list 'meow-expand-exclude-mode-list 'dired-mode)
    (add-to-list 'meow-expand-exclude-mode-list 'wdired-mode)))

(use-package selectrum
  :config
  (selectrum-mode 1))

(use-package prescient
  :config
  (prescient-persist-mode 1))

(use-package selectrum-prescient
  :after (selectrum prescient)
  :config
  (selectrum-prescient-mode 1)
  ;; 自定义按键
  (with-eval-after-load "selectrum"
    (define-key selectrum-minibuffer-map (kbd "{") #'selectrum-previous-candidate)
    (define-key selectrum-minibuffer-map (kbd "}") #'selectrum-next-candidate)))

(use-package smartparens
  :config
  (add-hook 'prog-mode-hook #'smartparens-mode)
  (add-hook 'conf-mode-hook #'smartparens-mode)
  (with-eval-after-load "smartparens"
    (define-key smartparens-mode-map (kbd "C-)") #'sp-forward-slurp-sexp)
    (define-key smartparens-mode-map (kbd "C-}") #'sp-forward-barf-sexp)
    (define-key smartparens-mode-map (kbd "M-r") #'sp-raise-sexp)
    (define-key smartparens-mode-map (kbd "M-s") #'sp-splice-sexp)))

(use-package magit
  :bind (("C-x g" . magit-status)))
;; (autoload #'magit "magit" nil t)
;; (global-set-key (kbd "C-x g") #'magit)

(use-package lsp-pyright
  :ensure t
  :config
  :hook
  (python-mode . (lambda ()
                   (require 'lsp-pyright)
                   (lsp-deferred))))

(use-package lsp-mode
  :commands lsp
  :hook (python-mode . lsp-deferred)
  :init (setq lsp-keymap-prefix "C-c l")
  :config
  (require 'lsp-pyright))

(use-package company
  :config
  (add-hook 'prog-mode-hook #'company-mode)
  (add-hook 'conf-mode-hook #'company-mode)
  (global-company-mode t)
  (setq company-idle-delay 0.2
        company-minimum-prefix-length 2
        company-show-numbers t
        company-dabbrev-ignore-case nil)
  (with-eval-after-load "company"
    (define-key company-active-map (kbd "{") #'company-select-previous)
    (define-key company-active-map (kbd "}") #'company-select-next)))

(use-package lsp-ui
  :commands lsp-ui-mode
  :hook (lsp-mode . lsp-ui-mode)
  :custom (lsp-ui-doc-enable t))

(set-frame-font "Hack Nerd Font Mono-10")
;; 隐藏工具栏, 菜单栏, 滚动条
(scroll-bar-mode -1)
(tool-bar-mode -1)
(menu-bar-mode -1)
(blink-cursor-mode -1)
(add-hook 'prog-mode-hook #'display-line-numbers-mode)
(add-hook 'conf-mode-hook #'display-line-numbers-mode)

;; 设置窗口大小
(add-to-list 'default-frame-alist '(width . 100))
(add-to-list 'default-frame-alist '(height . 45))

;; 禁止启动画面
(setq-default inhibit-startup-screen t
              indent-tabs-mode nil
              line-spacing 3)

;; 显示行号
(global-display-line-numbers-mode)
(global-hl-line-mode 1)

(setq scroll-conservatively 101
      scroll-margin 2)

;; 更改光标的样式
(setq cursor-type 'bar)

;; 不产生临时文件
(global-auto-revert-mode t)
(setq auto-save-default nil)
(setq make-backup-files nil)

;; 不响铃
(setq ring-bell-function 'ignore)

;; 自动配对括号
(electric-pair-mode t)

;; 启用语法高亮
(global-font-lock-mode t)

;; 显示空白字符
(global-whitespace-mode 0)
(add-hook 'before-save-hook 'delete-trailing-whitespace)
(setq whitespace-display-mappings '((space-mark 32 [183] [46]) ; 显示空格为点
                                    (tab-mark 9 [62 9] [92 9]))) ; 显示Tab为箭头
(setq-default show-trailing-whitespace t)

(global-unset-key (kbd "C-x C-n"))
(global-unset-key (kbd "C-x C-p"))
(global-unset-key (kbd "C-x C-b"))
(global-unset-key (kbd "C-x C-o"))
(global-set-key (kbd "<down>") 'scroll-up-line)
(global-set-key (kbd "<up>") 'scroll-down-line)
;; (global-set-key (kbd "C-f") 'scroll-up-command)
;; (global-set-key (kbd "C-b") 'scroll-down-command)

;; 启用 hs-minor-mode
(add-hook 'c-mode-common-hook 'hs-minor-mode)
(add-hook 'emacs-lisp-mode-hook 'hs-minor-mode)
(add-hook 'python-mode-hook 'hs-minor-mode)

;; 绑定快捷键
(global-set-key (kbd "C-c h") 'hs-hide-block) ;; 折叠当前代码块
(global-set-key (kbd "C-c s") 'hs-show-block) ;; 展开当前代码块
(global-set-key (kbd "C-c a") 'hs-hide-all) ;; 折叠所有代码
(global-set-key (kbd "C-c r") 'hs-show-all) ;; 展开所有代码
(global-set-key (kbd "C-c t") 'hs-toggle-hiding) ;; 切换当前代码块的折叠/展开状态
(global-set-key (kbd "C-x C-b") 'ibuffer)
(global-set-key (kbd "C-;") 'comment-dwim) ;; 代码注释

(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(package-selected-packages
   '(cnfonts company counsel doom-modeline doom-themes flycheck
             lsp-pyright lsp-ui magit meow modus-themes pop-mark
             python-mode restart-emacs selectrum-prescient smartparens)))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(meow-grab ((t (:inherit secondary-selection))))
 '(meow-insert-indicator ((t nil)))
 '(meow-keypad-indicator ((t nil)))
 '(meow-motion-indicator ((t nil)))
 '(meow-normal-indicator ((t nil))))
